/**
 * 2025/01/01 - 2025/12/31
 */
package com.snail.starter.iam.authentication.interfaces;

import com.snail.starter.commons.threadlocal.UserContext;
import com.snail.starter.commons.enums.HeaderEnums;
import com.snail.starter.iam.authentication.local.token.ITokenService;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Base64;

/**
 * @author zgadmin
 * @date 2025/8/26 14:28
 */
public abstract class AbstractAuthentication implements IAuthentication {

    @Resource
    ITokenService tokenService;

    public abstract UserContext basicToUserContext(String appType, long tenantId, String userName, String password);

    public UserContext authentication(HttpServletRequest request) {
        String token = analysisToken(request);
        if (null != token && !"".equals(token)) {
            return tokenService.get(token);
        }
        String authorization = request.getHeader(HeaderEnums.AUTHORIZATION.getKey());
        if (null != authorization && !"".equals(authorization)) {
            String credentialStr = new String(Base64.getDecoder().decode(authorization));
            String[] authorizationArray = credentialStr.split(":");
            if (2 == authorizationArray.length) {
                return basicToUserContext("", 0L, authorizationArray[0], authorizationArray[1]);
            }
            if (4 == authorizationArray.length) {
                return basicToUserContext(authorizationArray[0], Long.parseLong(authorizationArray[1]), authorizationArray[2], authorizationArray[3]);
            }
        }
        return UserContext.defaultContext();
    }

    private String analysisToken(HttpServletRequest request) {
        String token = request.getHeader(HeaderEnums.TOKEN.getKey());
        if (null != token && !"".equals(token)) {
            return token;
        }
        token = request.getParameter(HeaderEnums.TOKEN.getKey());
        if (null != token && !"".equals(token)) {
            return token;
        }
        Object tokenObj = request.getSession().getAttribute(HeaderEnums.TOKEN.getKey());
        if (null != tokenObj) {
            token = tokenObj.toString();
        }
        if (null != token && !"".equals(token)) {
            return token;
        }
        Cookie[] cookies = request.getCookies();
        if(null == cookies || 0 == cookies.length){
            return null;
        }
        for (Cookie cookie : cookies) {
            if (HeaderEnums.TOKEN.getKey().equalsIgnoreCase(cookie.getName())) {
                token = cookie.getValue();
            }
        }
        if (null != token && !"".equals(token)) {
            return token;
        }
        return null;
    }

}